Fix CPU-migration of VMX domains.
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 9 Feb 2006 11:10:28 +0000 (12:10 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 9 Feb 2006 11:10:28 +0000 (12:10 +0100)
Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
xen/arch/x86/hvm/vmx/vmcs.c
xen/arch/x86/hvm/vmx/vmx.c
xen/include/asm-x86/hvm/vmx/vmcs.h
xen/include/asm-x86/hvm/vmx/vmx.h

index 70bc6111f3a47789209ddfc91d9a66859eaee9c8..f79be0277e304329c1f9e849a8c4db32a95fc607 100644 (file)
@@ -75,6 +75,26 @@ static int load_vmcs(struct arch_vmx_struct *arch_vmx, u64 phys_ptr)
     return 0;
 }
 
+static void vmx_smp_clear_vmcs(void *info)
+{
+    struct vcpu *v = (struct vcpu *)info;
+
+    ASSERT(HVM_DOMAIN(v));
+
+    if (v->arch.hvm_vmx.launch_cpu == smp_processor_id())
+        __vmpclear(virt_to_maddr(v->arch.hvm_vmx.vmcs));
+}
+
+void vmx_request_clear_vmcs(struct vcpu *v)
+{
+    ASSERT(HVM_DOMAIN(v));
+
+    if (v->arch.hvm_vmx.launch_cpu == smp_processor_id())
+        __vmpclear(virt_to_maddr(v->arch.hvm_vmx.vmcs));
+    else
+        smp_call_function(vmx_smp_clear_vmcs, v, 1, 1);
+}
+
 #if 0
 static int store_vmcs(struct arch_vmx_struct *arch_vmx, u64 phys_ptr)
 {
@@ -167,6 +187,7 @@ static void vmx_set_host_env(struct vcpu *v)
     host_env.tr_base = (unsigned long) &init_tss[cpu];
     error |= __vmwrite(HOST_TR_SELECTOR, host_env.tr_selector);
     error |= __vmwrite(HOST_TR_BASE, host_env.tr_base);
+    error |= __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom());
 }
 
 static void vmx_do_launch(struct vcpu *v)
@@ -212,7 +233,6 @@ static void vmx_do_launch(struct vcpu *v)
     shadow_direct_map_init(v);
     __vmwrite(GUEST_CR3, pagetable_get_paddr(v->domain->arch.phys_table));
     __vmwrite(HOST_CR3, pagetable_get_paddr(v->arch.monitor_table));
-    __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom());
 
     v->arch.schedule_tail = arch_vmx_do_resume;
     v->arch.hvm_vmx.launch_cpu = smp_processor_id();
@@ -510,10 +530,11 @@ void arch_vmx_do_resume(struct vcpu *v)
     }
     else
     {
-        __vmpclear(virt_to_maddr(v->arch.hvm_vmx.vmcs));
+        vmx_request_clear_vmcs(v);
         load_vmcs(&v->arch.hvm_vmx, virt_to_maddr(v->arch.hvm_vmx.vmcs));
-        vmx_do_resume(v);
+        vmx_migrate_timers(v);
         vmx_set_host_env(v);
+        vmx_do_resume(v);
         v->arch.hvm_vmx.launch_cpu = smp_processor_id();
         reset_stack_and_jump(vmx_asm_do_relaunch);
     }
index 87324155ebcc48d5192d3c08ca1e528256695295..fd0edf127264f5ba2d1065b003a0c063b4043648 100644 (file)
@@ -91,6 +91,7 @@ void vmx_relinquish_resources(struct vcpu *v)
                (void *)d->arch.hvm_domain.shared_page_va);
     }
 
+    vmx_request_clear_vmcs(v);
     destroy_vmcs(&v->arch.hvm_vmx);
     free_monitor_pagetable(v);
     vpit = &v->domain->arch.hvm_domain.vpit;
@@ -338,6 +339,16 @@ int vmx_relinquish_guest_resources(struct vcpu *v)
     return 1;
 }
 
+void vmx_migrate_timers(struct vcpu *v)
+{
+    struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
+
+    migrate_timer(&vpit->pit_timer, v->processor);
+    migrate_timer(&v->arch.hvm_vmx.hlt_timer, v->processor);
+    if ( hvm_apic_support(v->domain) && VLAPIC(v))
+        migrate_timer(&(VLAPIC(v)->vlapic_timer), v->processor);
+}
+
 void vmx_store_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
 {
 #if defined (__x86_64__)
index 84b407367b284e531e9df97f47fc93adbbf21ddb..54820bcb2b1f07d47d09b862abb49b58ab6ff1ff 100644 (file)
@@ -95,6 +95,8 @@ int modify_vmcs(struct arch_vmx_struct *arch_vmx,
                 struct cpu_user_regs *regs);
 void destroy_vmcs(struct arch_vmx_struct *arch_vmx);
 
+extern void vmx_request_clear_vmcs(struct vcpu *v);
+
 #define VMCS_USE_HOST_ENV       1
 #define VMCS_USE_SEPARATE_ENV   0
 
index 52b0551c124083acd71dc8a310766292e67ee212..6d551edf8eafc64441902dc74cd2e3f9d9b19df0 100644 (file)
@@ -31,7 +31,7 @@ extern void vmx_asm_do_resume(void);
 extern void vmx_asm_do_launch(void);
 extern void vmx_intr_assist(void);
 extern void vmx_set_tsc_shift(struct vcpu *, struct hvm_virpit *);
-
+extern void vmx_migrate_timers(struct vcpu *v);
 extern void arch_vmx_do_launch(struct vcpu *);
 extern void arch_vmx_do_resume(struct vcpu *);